﻿using System;
using System.Collections.Generic ;
using System.ComponentModel;
using System.Data ;
using System.Linq;
  
namespace LayerEntity.Compras
{
    public class ECompra  
    {
        #region Variables
        BindingList<EDetalleCompra> listItem; 
        //List<EDetalleCompra> listItem = new List<EDetalleCompra>();
        readonly List<EDetalleCompra> listRemove = new List<EDetalleCompra>();
        public delegate void RefreshList();
        public event RefreshList UpdateList = delegate { };
        double factorFlete = 0.0;
        #endregion

        #region Constructores

        public ECompra(IDataRecord record)
        {
            this.Anio = record["anio"].ToString().Trim();
            this.IdCompra = record["idcompra"].ToString().Trim();
            this.IdMes = record["idmes"].ToString().Trim();
            this.IdDocumento = Convert.ToInt32(record["id_documento"].ToString());
            this.NumeroDocumento = record["nro_doc_compra"].ToString().Trim();
            this.IdDireccionProveedor = (int) record["id_dir_proveedor"];
            if (record["fec_ing_almacen"] != DBNull.Value)
            {
                this.FechaAlmacen = Convert.ToDateTime(record["fec_ing_almacen"].ToString());
            }
            
            this.FechaRegistro = DateTime.Parse(record["fec_ing_sistema"].ToString());

            this.FechaDocumento = Convert.ToDateTime(record["fec_documento"].ToString());
            this.Importe = (double ) record["imp_venta"];
            this.Descuento = (double )record["imp_dctso"];
            this.PorcentajeDescuento = (double ) record["porcent_dscto"];
            this.IdSucursal = (int) record["id_sucursal"];
            this.ImporteReintegro = (double )record["val_reintegro"];
            this.ReintegroTributario = Convert.ToBoolean(Convert.ToInt32(record["reintegro_tributario"].ToString()));
            this.ImporteIgv = (double ) record["imp_igv"];
            this.Persepcion = (double ) record["persepcion"];
            this.GenerarLetras = Convert.ToBoolean(Convert.ToInt32(record["genera_letras"].ToString()));
            this.ActualizarPrecios = Convert.ToBoolean(Convert.ToInt32(record["actualiza_precios"].ToString()));
            this.MercaderiaTransito = Convert.ToBoolean(Convert.ToInt32(record["mercaderia_transito"].ToString()));
            this.IdMoneda = (int)record["id_moneda"];
            this.IdUsuarioUpdate = record["idusuario_a"].ToString();
            this.IdUsuarioRegistra = record["idusuario_r"].ToString();
            this.FechaUpdate = DateTime.Parse(record["date_act"].ToString());
            this.IdFormaPago = (int )record["id_formapago"];
            this.IdProveedor = record["id_proveedor"].ToString();
            this.IdOperacion = record["id_operacion"].ToString();
            this.IdIgv = (int) record["id_igv"];
            this.listItem = new BindingList<EDetalleCompra>();
            this.listRemove = new List<EDetalleCompra>();
            //listItem.AddingNew += new AddingNewEventHandler(AddNewItem);
        }

        public ECompra()
        {
            this.Anio = string.Empty ;
            this.IdCompra = string.Empty ;
            this.IdMes = string.Empty ;
            this.IdDocumento = -1;
            this.NumeroDocumento = string.Empty ;
            this.IdDireccionProveedor = -1;
            this.IdIgv = 0;
            this.Importe = 0.0;
            this.Descuento = 0.0;
            this.PorcentajeDescuento = 0.0;
            this.IdSucursal = -1;
            this.ImporteReintegro = 0.0;
            this.ReintegroTributario = false ;
            this.ImporteIgv = 0.0;
            this.Persepcion = 0.0;
            this.GenerarLetras = false ;
            this.ActualizarPrecios = false ;
            this.MercaderiaTransito = false ;
            this.IdMoneda = -1;
            this.IdUsuarioUpdate = string.Empty ;
            this.IdUsuarioRegistra = string.Empty ;
            
            this.IdFormaPago = 0;
            this.IdProveedor = "";
            this.IdOperacion = string.Empty ;
            this.listItem = new BindingList<EDetalleCompra>();
            this.listRemove = new List<EDetalleCompra>();
            listItem .AddingNew += new AddingNewEventHandler(AddNewItem);
            listItem .ListChanged += new ListChangedEventHandler(ItemListChanged);
        }

        void ItemListChanged(object sender, ListChangedEventArgs e)
        { 
        }

        void AddNewItem(object sender, AddingNewEventArgs e)
        {
            EDetalleCompra det = new EDetalleCompra();
            det.Item = this.NextIdDetalle();
            e.NewObject = det;
        }

        #endregion

        #region Propiedades

        public string Anio { get; set; }
        public string IdCompra { get; set; }
        public string IdMes { get; set; }
        public int IdDocumento { get; set; }
        public string NumeroDocumento { get; set; }
        public int IdDireccionProveedor { get; set; }
        public DateTime FechaAlmacen { get; set; }
        public DateTime FechaRegistro { get; set; }
        public DateTime FechaDocumento { get; set; }
        public double Importe { get; set; }
        public double Descuento { get; set; }
        public double PorcentajeDescuento { get; set; }
        public int IdSucursal { get; set; }
        public double ImporteReintegro { get; set; }
        public bool ReintegroTributario { get; set; }
        public double ImporteIgv { get; set; }
        public double Persepcion { get; set; }
        public bool GenerarLetras { get; set; }
        public bool ActualizarPrecios { get; set; }
        public bool MercaderiaTransito { get; set; }
        public int IdMoneda { get; set; }
        public string IdUsuarioUpdate { get; set; }
        public string IdUsuarioRegistra { get; set; }
        public DateTime FechaUpdate { get; set; }
        public int IdFormaPago { get; set; }
        public string IdProveedor { get; set; }
        public string IdOperacion { get; set; }
        public int IdIgv { get; set; }
        public double FactorFlete { get; set; }
        #endregion

        #region Metodos
        public void AddItem(EDetalleCompra item)
        {
            if (this.listItem == null)
            {
                this.listItem = new BindingList<EDetalleCompra>();
            }
            if (item != null)
            {
                int index = listItem.ToList().FindIndex(delegate(EDetalleCompra c)
                {
                    return c.Item == item.Item;
                });
                if (index < 0)
                {
                    this.listItem.Add(item);
                }
                else
                {
                    listItem[index] = item;
                }
                UpdateFlete(this.factorFlete, EnumTipoFlete.Peso);
                this.UpdateList();
            }
        }

        public void AddItem(List<EDetalleCompra> items)
        {
            if (items != null)
            {
                foreach (EDetalleCompra item in items)
                {
                    this.AddItem(item);
                }
            }
        }

        public void RemoveItem(EDetalleCompra item)
        {
            if (this.listItem != null)
            {
                if (this.listItem.Count > 0)
                {
                    if (item != null)
                    {
                        RemoveItem(item.Item);
                    }
                }
            }
        }

        public void RemoveItem(int id)
        {
            if (id > -1)
            {
                if (listItem != null)
                {
                    int index = listItem.ToList().FindIndex(delegate(EDetalleCompra c) { return c.Item == id; });
                    
                    if (index > -1)
                    {
                        EDetalleCompra itemRemove = this.listItem[index];
                        listRemove.Add(itemRemove);
                        listItem.RemoveAt(index);
                        this.UpdateList();
                    }
                }
            }
        }

        public void RemoveItem(List<EDetalleCompra> items)
        {
            if (items != null)
            {
                foreach (EDetalleCompra item in items)
                {
                    this.RemoveItem(item);
                }
            }
        }

        public void UpdateFlete(double flete, EnumTipoFlete tipo)
        {
            factorFlete = 0.0;
            if (listItem.Count > 0)
            {
                if (flete > 0)
                {
                    if (tipo == EnumTipoFlete.Peso)
                    {
                        List<double> peso = (from item in this.listItem select (item.Cantidad * item.Peso)).ToList();
                        if (peso.Count > 0)
                        {
                            double suma = peso.Sum();
                            if (suma > 0)
                            {
                                this.factorFlete = Math.Round(flete / peso.Sum(), 2);
                            }
                        }
                    }
                    else
                    {
                        List<double> cantidad = (from item in this.listItem select (item.Cantidad * 1.0)).ToList();
                        if (cantidad.Count > 0)
                        {
                            double suma = cantidad.Sum();
                            if (suma > 0)
                            {
                                this.factorFlete = Math.Round(flete / cantidad.Sum(), 2);
                            }
                        }
                    }
                }
            }
            foreach (EDetalleCompra c in listItem)
            {
                c.Flete = factorFlete;
                //if (c.Item == 0)
                //{
                //    c.Item = NextIdDetalle();
                //}
            }
            //this.UpdateList();
        }

        #endregion

        #region Funciones

        public BindingList <EDetalleCompra> GetDetalle()
        {
            return listItem;
        }

        public int NextIdDetalle()
        {
            if (listItem.Count == 0)
            {
                return 1;
            }
            else
            { 
                return (from i in listItem orderby i.Item descending select i.Item + 1).Take(1).ToList().First();
            }
        }

        public double GetAfecto()
        {
            if (listItem.Count > 0)
            {
                return (from i in listItem where i.PorcentajeIgv > 0.0 select i.SubTotal).Sum();
            }
            else
            {
                return 0.0;
            }
        }

        public double GetExonerado()
        {
            if (listItem.Count > 0)
            {
                return (from i in listItem where i.PorcentajeIgv == 0.0 select i.SubTotal).Sum();
            }
            else
            {
                return 0.0;
            }
        }

        public double GetIgv()
        {
            if (listItem.Count > 0)
            {
                return (from i in listItem select i.Igv).Sum();
            }
            else
            {
                return 0.0;
            }
        }

        public double GetTotal()
        {
            if (listItem.Count > 0)
            {
                return (from i in listItem select i.SubTotal).Sum();
            }
            else
            {
                return 0.0;
            }
        }

        public double GetDescuento()
        {
            if (listItem.Count > 0)
            {
                return (from i in listItem select i.Descuento).Sum();
            }
            else
            {
                return 0.0;
            }
        }

        public double GetPorcentajeDescuento()
        {
            if (listItem.Count > 0)
            {
                double suma = GetTotal() + GetDescuento();
                if (suma > 0)
                {
                    return Math.Round((GetDescuento() * 100) / suma, 2);
                }
                else
                {
                    return 0.0;
                }
            }
            else
            {
                return 0.0;
            }
        }

        public EDetalleCompra GetItem(int id)
        { 
            return listItem.ToList().Find(delegate(EDetalleCompra c)
            {
                return c.Item == id;
            });
        }

        public object[] ToObject()
        {
            object[] obj = null;
            obj = new object[]
            {
                this.Anio,
                this.IdCompra,
                this.IdMes,
                this.IdDocumento,
                this.NumeroDocumento,
                this.IdDireccionProveedor,
                this.FechaRegistro,
                this.FechaDocumento,
                this.Importe,
                this.ImporteIgv,
                0.0,
                this.Descuento,
                this.PorcentajeDescuento,
                this.IdSucursal,
                this.ImporteReintegro ,
                this.Persepcion,
                this.IdMoneda,
                this.IdUsuarioRegistra,
                this.IdFormaPago,
                this.IdProveedor,
                this.IdOperacion,
            };
            return obj;
        }
        #endregion
    }
}